var winY = window.innerHeight - 23;
var winX = window.innerWidth - 15;
var fireworks = [];
var particles = [];
var myCanvas = document.querySelector('#myCanvas');
myCanvas.width = winX;
myCanvas.height = winY;
var ctx = myCanvas.getContext('2d');
var conf = {};

function random(min, max){
	return Math.random() * (max - min) + min;
}
function getDistance(x1, y1, x2, y2){
	var x = x1 - x2;
	var y = y1 - y2;
	return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
function Firework (conf){
	this.sx = conf['startX'] || winX/2;
	this.sy = conf['startY'] || winY;

	this.ex = conf['endX'];
	this.ey = conf['endY'];

	this.x = this.sx;
	this.y = this.sy;

	this.angle = Math.atan2(this.ey-this.sy, this.ex-this.sx);

	this.distanceToTarget = getDistance(this.sx, this.sy,  conf['endX'], conf['endY']);

	this.speed = conf['speed'] || 10;
	this.acceleration = conf['acceleration'] || 1.05;

	this.coordinates = [];
	this.coordinatesCount = conf['coordinatesCount'] || 4;
	while(this.coordinatesCount --){
		this.coordinates.push( [this.sx, this.sy] );
	}

	this.hue = conf['hue'] || 120;
	this.lightness = conf['lightness'] || 50;

	this.particleCount = conf['particleCount'] || 300;
}
Firework.prototype.render = function (){
	ctx.beginPath();
	ctx.globalAlpha = 1;
	ctx.moveTo(this.x, this.y);
	ctx.lineTo(this.coordinates[0][0], this.coordinates[0][1]);
	ctx.strokeStyle = 'hsl('+this.hue+', 100%, '+this.lightness+'%)';
	ctx.stroke();
	ctx.lineTo(this.coordinates[1][0], this.coordinates[1][1]);
	ctx.globalAlpha = 0.4;
	ctx.stroke();
	ctx.lineTo(this.coordinates[3][0], this.coordinates[3][1]);
	ctx.globalAlpha = 0.2;
	ctx.stroke();
}
Firework.prototype.update = function(index){
	this.coordinates.pop(index);

	this.coordinates.unshift([this.x, this.y]);

	this.speed *= this.acceleration;

	var vx = Math.cos(this.angle) * this.speed,
		vy = Math.sin(this.angle) * this.speed;

	this.traveled = getDistance(this.sx, this.sy, this.x+vx, this.y+vy);

	if(this.traveled >= this.distanceToTarget){

		var particleCount = this.particleCount;
		while(particleCount--){
			particles.push(new Particle(this.x, this.y, this.hue));
		}
		fireworks.splice(index, 1);
	}else{
		this.x += vx;
		this.y += vy;
	}
}
function Particle(x, y, hue){
	this.x = x;
	this.y = y;

	this.coordinates = [];
	this.coordinateCount = 6;
	while(this.coordinateCount --){
		this.coordinates.push([this.x, this.y]);
	}

	this.angle = random(0, Math.PI * 2);
	this.speed = random(1, 32);

	this.hue = hue;
	this.lightness = Math.floor(random(50, 60));

	this.frication = 0.95;
	this.gravity = 1.4;

	this.alpha = 1;
	this.decay = random(0.005, 0.05);
}
Particle.prototype.render = function() {
	ctx.beginPath();
	ctx.globalAlpha = 1;
	ctx.moveTo(this.x, this.y);
	ctx.lineTo(this.coordinates[1][0], this.coordinates[1][1]);
	ctx.strokeStyle = 'hsla(' + this.hue + ', 100%, '+this.lightness+'%, ' + this.alpha +')';

	ctx.stroke();
	ctx.lineTo(this.coordinates[3][0], this.coordinates[3][1]);
	ctx.globalAlpha = 0.6;
	ctx.stroke();
	ctx.lineTo(this.coordinates[5][0], this.coordinates[5][1]);
	ctx.globalAlpha = 0.4;

	ctx.stroke();
}
Particle.prototype.update = function(index){
	this.coordinates.pop();
	this.coordinates.unshift([this.x, this.y]);

	this.speed *= this.frication;

	this.x += Math.sin(this.angle) * this.speed;
	this.y += Math.cos(this.angle) * this.speed + this.gravity;

	this.alpha -= this.decay;

	if(this.alpha < this.decay){
		particles.splice(index, 1);
	}
}

var timerTick = 41;
var timerTotal = 40;
function frameUpdate(count){

	var i = fireworks.length;

	while(i --){
		fireworks[i].render();
		fireworks[i].update(i);
	}
	i = particles.length;
	while(i --){
		particles[i].render();
		particles[i].update(i);
	}

	if(timerTick > timerTotal){
		while(count --){
			conf['hue'] = Math.floor(random(0, 360));
			conf['endX'] = random(0, winX);
			conf['endY'] = random(0, winY/2);
			conf['particleCount'] = Math.floor(random(100, 200));
			fireworks.push(new Firework(conf));
		}
		timerTick = 0;
	}else{
		timerTick ++;
	}

}